enum equality {
    EQUALTO,
    GREATERTHAN,
    LESSTHAN,
    GREATEROREQUAL,
    LESSOREQUAL,
    PREGMATCH,
    STARTSWITH,
    ENDSWITH
};

enum filter_match_t {
    MATCH,
    FAIL,
    DROP
};

struct filter_t {
    char *name;
    char *value;
    int (*cmp)(void*,void*);
    struct filter_t *next;
};

struct listener_t {
    plugin *origin;
    int priority; /* puts it at the head of the list, not the tail. useful for listeners that want to silence events */ 
    struct filter_t *head;
    struct filter_t *tail;
    struct listener_t *next;
};

struct field_t {
    char *name;
    char *value;
};

struct event_t {
    plugin *source;
    int num_fields;
    struct field_t **fields;
};

#define MAX_FIELDS 16

typedef struct listener_t listener;
typedef struct filter_t filter;
typedef struct event_t event;
typedef struct field_t field;
typedef enum filter_match_t filter_match;

void events_init(void);

void cmd_event(plugin*,const char **argv, int argc);
void cmd_event_listen(plugin*, const char **argv, int argc);
void listener_add(listener*);
void event_finished();
void exec_event(event *evt);
filter_match match(filter *_filter, event *_event);
char *evt2str(event*);
int cmp_eq(void*,void*);
int cmp_ge(void*,void*);
int cmp_le(void*,void*);
int cmp_streq(void*,void*);

extern listener *listeners;
